﻿using Cl.Model.Results;
using Cl.Service.ElsaWorkflow.Activity.ClAudit.BookMarks;
using Cl.Service.ElsaWorkflow.Activity.ClAudit.Models;
using Cl.Service.ElsaWorkflow.Activity.ClAudit;
using Elsa.Models;
using Elsa.Services.Models;
using Elsa.Services.Workflows;
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elsa.Activities.Signaling.Services;
using Elsa.Services;
using Cl.Repository;
using Cl.Entity.WorkflowEntity;
using Cl.Utils;

namespace Cl.Service.Service.Workflows
{
    public class ElsaWorkflow : IElsaWorkflow
    {
        private CLBaseRepository<WorkFlowDefinitions> WorkFlowDefinitionsRepository;
        private readonly IWorkflowLaunchpad WorkFlowLaunchpad;
        private readonly ISignaler WorkFlowSignaler;
        private CLBaseRepository<WorkflowInstances> WorkflowInstancesRepository;
        public ElsaWorkflow(CLBaseRepository<WorkFlowDefinitions> workFlowDefinitionsRepository, IWorkflowLaunchpad workFlowLaunchpad,
            ISignaler workFlowSignaler, CLBaseRepository<WorkflowInstances> workflowInstancesRepository)
        {
            WorkFlowDefinitionsRepository = workFlowDefinitionsRepository;
            WorkFlowLaunchpad = workFlowLaunchpad;
            WorkFlowSignaler = workFlowSignaler;
            WorkflowInstancesRepository = workflowInstancesRepository;
        }

        public async Task<ResultInfoModel> AuditWorkFlowAsync(string workName, string activeName, string contextId, string userCode, bool auditStatus, string remark, string entityId)
        {
            WorkFlowAuditInput wtmApproveInputData = new WorkFlowAuditInput();
            string actionName = string.Empty;
            if (auditStatus)
                actionName = "同意";
            else
                actionName = "拒绝";
            wtmApproveInputData.Action = actionName;
            wtmApproveInputData.Remark = remark;
            wtmApproveInputData.UserId = GlobalUserManager.UserId;
            wtmApproveInputData.EntityId = entityId.ToString();

            AuditActivityBookMark inputObj = new AuditActivityBookMark(userCode, workName, activeName, contextId);//YiShen
            var className = typeof(AuditActivity).Name;
            WorkflowsQuery workflowsQuery = new WorkflowsQuery(className, inputObj, null, null, null, null);

            var findWorkFlow = await WorkFlowLaunchpad.FindWorkflowsAsync(workflowsQuery);
            //int count = 0;
            foreach (CollectedWorkflow item in findWorkFlow)
            {
                if (item.WorkflowInstance == null)
                {
                    await WorkFlowLaunchpad.ExecutePendingWorkflowAsync(item, new WorkflowInput
                    {
                        Input = wtmApproveInputData
                    });
                }
            }
            return GetResult.Success();
        }

        public async Task<ResultInfoModel> IsAllowUseAudit(string workName, string activeName, string userCode, string contextId)
        {
            AuditActivityBookMark inputObj = new AuditActivityBookMark(userCode, workName, activeName, contextId);//YiShen
            var className = typeof(AuditActivity).Name;
            WorkflowsQuery workflowsQuery = new WorkflowsQuery(className, inputObj, null, null, null, null);

            var findWorkFlow = await WorkFlowLaunchpad.FindWorkflowsAsync(workflowsQuery);
            if (findWorkFlow.Count() > 0)
                return GetResult.Success();
            else
                return GetResult.Error("无权审核！");
        }

        public async Task<ResultInfoModel> SendWorkflowSignal(List<string> contextIds, string signalerName)
        {
            var workInstanceIds = WorkflowInstancesRepository.GetList(x => !string.IsNullOrEmpty(x.ContextId) && contextIds.Contains(x.ContextId)).Select(x => x.Id).ToList();

            foreach (var workInstanceId in workInstanceIds)
            {
                await WorkFlowSignaler.TriggerSignalAsync(signalerName, workflowInstanceId: workInstanceId);
            }

            return GetResult.Success();
        }

        public async Task<ResultInfoModel> StartAuditWorkFlowAsync(string auditWorkName, string contextId)
        {
            //var auditWorkName = "LimsWorkFlowAudit";
            var auditWork = WorkFlowDefinitionsRepository.GetFirst(x => x.Name == auditWorkName && x.IsPublished == true);
            if (auditWork == null)
            {
                return GetResult.Error("找不到需要开启的工作流");
            }
            StartableWorkflow? startableWorkflow = await WorkFlowLaunchpad.FindStartableWorkflowAsync(auditWork.DefinitionId, null, null, contextId);
            if (startableWorkflow == null)
            {
                return GetResult.Error("找不到需要开启的工作流");
            }
            startableWorkflow.WorkflowInstance.Name = auditWorkName;
            var workInfo = await WorkFlowLaunchpad.ExecuteStartableWorkflowAsync(startableWorkflow);
            return GetResult.Success(workInfo.WorkflowInstance.Id);
        }
    }
}
